﻿using ProjBackEnd.Areas.BizProj.Models;
using ProjBackEnd.Areas.ExtPub.Models;
using ProjBackEnd.Areas.Financial.Models;
using ProjBackEnd.DAL;
using ProjBackEnd.Lib;
using ProjBackEnd.Models;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Reflection;
using System.Text;
using System.Web.Http;
using System.Web.Security;
using System.Xml;

namespace ProjBackEnd.Areas.ExtPub.Controllers
{
    /// <summary>
    /// 微信公众平台对接
    /// </summary>
    [RoutePrefix("api/extpub")]
    public class WxPublicController : ApiController
    {
        /// <summary>
        /// 微信用户登录
        /// </summary>
        /// <param name="_reqInfo"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("wxuserlogin")]
        public RespWxUserInfo WxUserLogin(ReqWxUserLogin _reqInfo)
        {
            if (_reqInfo == null) return new RespWxUserInfo { statusCode = 90002, statusMsg = GlobalSettings.MSG_BADREQUEST };
            return extPubWxLogic.GetWxUserInfo(_reqInfo.pubid, _reqInfo.wxcode, _reqInfo.nickname, _reqInfo.avatarurl);
        }

        /// <summary>
        /// 获取我的审批列表
        /// </summary>
        /// <param name="_reqInfo"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("myapprovallist")]
        public RespWxMyApprovalList MyApprovalList(ReqMyApprovalList _reqInfo)
        {
            if (_reqInfo == null) return new RespWxMyApprovalList { statusCode = 90002, statusMsg = GlobalSettings.MSG_BADREQUEST };
            if (!ModelState.IsValid) return new RespWxMyApprovalList { statusCode = 90004, statusMsg = GlobalSettings.MSG_FORMATERROR + DataUtil.GetModelStateError(ModelState) };
            string strWxToken = "";
            if (!DataUtil.CheckTokenExist(Request, out strWxToken)) return new RespWxMyApprovalList { statusCode = 90002, statusMsg = GlobalSettings.MSG_BADREQUEST };
            if (!extPubWxLogic.CheckWxToken(_reqInfo.openid+"@"+_reqInfo.personid.ToString(), strWxToken)) return new RespWxMyApprovalList { statusCode = 90002, statusMsg = GlobalSettings.MSG_BADREQUEST };
            return extPubWxLogic.GetWxMyApprovalList(_reqInfo.personid, _reqInfo.comcd, _reqInfo.applytp, _reqInfo.revlb, _reqInfo.pagesize, _reqInfo.currpage);
        }

        /// <summary>
        /// 获取审批明细
        /// </summary>
        /// <param name="_reqInfo"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("approvaldetail")]
        public RespWxApprovalDetail ApprovalDetail(ReqApprovalDetail _reqInfo)
        {
            if (_reqInfo == null) return new RespWxApprovalDetail { statusCode = 90002, statusMsg = GlobalSettings.MSG_BADREQUEST };
            if (!ModelState.IsValid) return new RespWxApprovalDetail { statusCode = 90004, statusMsg = GlobalSettings.MSG_FORMATERROR + DataUtil.GetModelStateError(ModelState) };
            string strWxToken;
            if (!DataUtil.CheckTokenExist(Request, out strWxToken))
                return new RespWxApprovalDetail { statusCode = 90002, statusMsg = GlobalSettings.MSG_BADREQUEST };
            if (!extPubWxLogic.CheckWxToken(_reqInfo.openid + "@" + _reqInfo.personid.ToString(), strWxToken))
                return new RespWxApprovalDetail { statusCode = 90002, statusMsg = GlobalSettings.MSG_BADREQUEST };
            return extPubWxLogic.GetWxApprovalDetail(_reqInfo.personid, _reqInfo.applyid, _reqInfo.applytp, _reqInfo.revlb);
        }

        /// <summary>
        /// 获取审批单所属的账单明细
        /// </summary>
        /// <param name="_reqInfo"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("approvalbilldetail")]
        public RespBizFee ApprovalBillDetail(ReqApprovalBillDetail _reqInfo)
        {
            if (_reqInfo == null) return new RespBizFee { statusCode = 90002, statusMsg = GlobalSettings.MSG_BADREQUEST };
            if (!ModelState.IsValid) return new RespBizFee { statusCode = 90004, statusMsg = GlobalSettings.MSG_FORMATERROR + DataUtil.GetModelStateError(ModelState) };
            string strWxToken;
            if (!DataUtil.CheckTokenExist(Request, out strWxToken))
                return new RespBizFee { statusCode = 90002, statusMsg = GlobalSettings.MSG_BADREQUEST };
            if (!extPubWxLogic.CheckWxToken(_reqInfo.openid + "@" + _reqInfo.personid.ToString(), strWxToken))
                return new RespBizFee { statusCode = 90002, statusMsg = GlobalSettings.MSG_BADREQUEST };
            return extPubWxLogic.GetBillDetail(_reqInfo.billid);
        }

        /// <summary>
        /// 提交审批结果
        /// </summary>
        /// <param name="_reqInfo"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("reviewsubmit")]
        public RespFinaNullResultInfo ReviewSubmit(ReqRevSubmit _reqInfo)
        {
            if (_reqInfo == null) return new RespFinaNullResultInfo { statusCode = 90002, statusMsg = GlobalSettings.MSG_BADREQUEST };
            if (!ModelState.IsValid) return new RespFinaNullResultInfo { statusCode = 90004, statusMsg = GlobalSettings.MSG_FORMATERROR + DataUtil.GetModelStateError(ModelState) };
            string strWxToken = "";
            if (!DataUtil.CheckTokenExist(Request, out strWxToken))
                return new RespFinaNullResultInfo { statusCode = 90002, statusMsg = GlobalSettings.MSG_BADREQUEST };
            if (!extPubWxLogic.CheckWxToken(_reqInfo.openid + "@" + _reqInfo.personid.ToString(), strWxToken))
                return new RespFinaNullResultInfo { statusCode = 90002, statusMsg = GlobalSettings.MSG_BADREQUEST };
            switch (_reqInfo.applytp.ToUpper())
            {
                case GlobalSettings.APPLYTP_BILL:
                    return financialLogic.BillApprove("", _reqInfo.applyid, _reqInfo.revlb, _reqInfo.sortval, _reqInfo.reason, _reqInfo.personid);
                case GlobalSettings.APPLYTP_FN:
                    return financialLogic.FnApprove("", _reqInfo.applyid, _reqInfo.revlb, _reqInfo.sortval, _reqInfo.reason, _reqInfo.personid);
                default:
                    return new RespFinaNullResultInfo { statusCode = 90002, statusMsg = GlobalSettings.MSG_BADREQUEST + "@" + _reqInfo.applytp };
            }

        }

        /// <summary>
        /// 更新绑定用户信息
        /// </summary>
        /// <param name="_reqInfo"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("bindmemberopt")]
        [Route("wxbindmemberopt")]
        public RespWxNullResultInfo UpdateBindMember(ReqBindMember _reqInfo)
        {
            if (_reqInfo == null) return new RespWxNullResultInfo { statusCode = 90002, statusMsg = GlobalSettings.MSG_BADREQUEST };
            if (!ModelState.IsValid) return new RespWxNullResultInfo { statusCode = 90004, statusMsg = GlobalSettings.MSG_FORMATERROR + DataUtil.GetModelStateError(ModelState) };
            string strWxToken = "";
            if (!DataUtil.CheckTokenExist(Request, out strWxToken))
                return new RespWxNullResultInfo { statusCode = 90002, statusMsg = GlobalSettings.MSG_BADREQUEST };
            if (!extPubWxLogic.CheckWxToken(_reqInfo.openid + "@" + _reqInfo.personid.ToString(), strWxToken))
                return new RespWxNullResultInfo { statusCode = 90002, statusMsg = GlobalSettings.MSG_BADREQUEST };
            //用户绑定操作
            return extPubWxLogic.UpdateBindMember(_reqInfo.userid, _reqInfo.password, _reqInfo.memberid, _reqInfo.personid, _reqInfo.optlb);
        }

        /// <summary>
        /// 获取已绑定用户列表
        /// </summary>
        /// <param name="_reqInfo"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("wxmemberlist")]
        public RespWxBindMember GetBindMemberInfo(BaseWxUserRequest _reqInfo)
        {
            if (_reqInfo == null) return new RespWxBindMember { statusCode = 90002, statusMsg = GlobalSettings.MSG_BADREQUEST };
            if (!ModelState.IsValid) return new RespWxBindMember { statusCode = 90004, statusMsg = GlobalSettings.MSG_FORMATERROR + DataUtil.GetModelStateError(ModelState) };
            string strWxToken = "";
            if (!DataUtil.CheckTokenExist(Request, out strWxToken))
                return new RespWxBindMember { statusCode = 90002, statusMsg = GlobalSettings.MSG_BADREQUEST };
            if (!extPubWxLogic.CheckWxToken(_reqInfo.openid + "@" + _reqInfo.personid.ToString(), strWxToken))
                return new RespWxBindMember { statusCode = 90002, statusMsg = GlobalSettings.MSG_BADREQUEST };
            return extPubWxLogic.GetBindMemberInfo(_reqInfo.personid);
        }

        /// <summary>
        /// 公众号验证接口
        /// * 将token、timestamp、nonce三个参数进行字典序排序
        /// * 将三个参数字符串拼接成一个字符串进行sha1加密
        /// * 开发者获得加密后的字符串可与signature对比，标识该请求来源于微信。
        /// </summary>
        /// <param name="signature"></param>
        /// <param name="timestamp"></param>
        /// <param name="nonce"></param>
        /// <param name="echostr"></param>
        /// <returns></returns>
        [HttpGet]
        [Route("azsvrhandle")]
        public HttpResponseMessage CheckWxRequest(string signature,string timestamp,string nonce,string echostr)
        {
            
            if (string.IsNullOrEmpty(echostr)) return new HttpResponseMessage(HttpStatusCode.BadRequest);
            InnerResultWxPubConfig resPubConfig = extPubWxLogic.GetPubInfo(1); //az服务号id
            if(resPubConfig==default(InnerResultWxPubConfig)) new HttpResponseMessage(HttpStatusCode.BadRequest);

            string[] ArrTmp = { resPubConfig.apptoken, timestamp, nonce };
            Array.Sort(ArrTmp);     //字典排序
            string tmpStr = string.Join("", ArrTmp);
            System.Security.Cryptography.SHA1 algorithm = System.Security.Cryptography.SHA1.Create();
            byte[] data = algorithm.ComputeHash(Encoding.UTF8.GetBytes(tmpStr));
            string sh1 = "";
            for (int i = 0; i < data.Length; i++) sh1 += data[i].ToString("x2").ToUpperInvariant();
            tmpStr = sh1.ToLower();
            if (tmpStr == signature)
            {
                HttpResponseMessage resp = new HttpResponseMessage(HttpStatusCode.OK);
                resp.Content = new StringContent(echostr, Encoding.UTF8);
                return resp;
            }
            else
            {
                DataUtil.WriteLog(MethodBase.GetCurrentMethod().Name, signature + ";" + timestamp + ";" + nonce + "@" + tmpStr);
                return new HttpResponseMessage(HttpStatusCode.BadRequest);
            }
        }

        /// <summary>
        /// Handle WeChat Message
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        [Route("azsvrhandle")]
        public HttpResponseMessage ResponseWxMessage()
        {
            try
            {
                Stream s = System.Web.HttpContext.Current.Request.InputStream;
                byte[] b = new byte[s.Length];
                s.Read(b, 0, (int)s.Length);
                string strPost = Encoding.UTF8.GetString(b);
                DataUtil.WriteLog(MethodBase.GetCurrentMethod().Name, strPost);
                if (string.IsNullOrEmpty(strPost)) return new HttpResponseMessage(HttpStatusCode.BadRequest);

                XmlDocument doc = new XmlDocument();
                doc.LoadXml(strPost);
                XmlElement rootElement = doc.DocumentElement;

                XmlNode MsgType = rootElement.SelectSingleNode("MsgType");

                ExtWxRequestXML requestXML = new ExtWxRequestXML();
                requestXML.ToUserName = rootElement.SelectSingleNode("ToUserName").InnerText;
                requestXML.FromUserName = rootElement.SelectSingleNode("FromUserName").InnerText;
                requestXML.CreateTime = rootElement.SelectSingleNode("CreateTime").InnerText;
                requestXML.MsgType = MsgType.InnerText;
                string strKey = "";
                int iSubscribe = 0;
                switch (requestXML.MsgType)
                {
                    case "event":

                        strKey = rootElement.SelectSingleNode("Event").InnerText.ToLower();
                        if (strKey == "subscribe") iSubscribe = 1;
                        else if (strKey == "unsubscribe") iSubscribe = 0;
                        else break;
                        extPubWxLogic.PubPlatformUserOpt(1, requestXML.FromUserName, iSubscribe);
                        break;
                    default:break;
                }
                return new HttpResponseMessage(HttpStatusCode.OK);
            }
            catch (Exception ex)
            {
                DataUtil.WriteLog(MethodBase.GetCurrentMethod().Name, ex.Message);
                return new HttpResponseMessage(HttpStatusCode.BadRequest);
            }

        }


    }
}
